// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CommonLocalPlayer.h"
#include "Teams/LyraTeamAgentInterface.h"

#include "LyraLocalPlayer.generated.h"

#define UE_API LYRAGAME_API

struct FGenericTeamId;

class APlayerController;
class UInputMappingContext;
class ULyraSettingsLocal;
class ULyraSettingsShared;
class UObject;
class UWorld;
struct FFrame;
struct FSwapAudioOutputResult;

/**
 * ULyraLocalPlayer
 */
UCLASS(MinimalAPI)
class ULyraLocalPlayer : public UCommonLocalPlayer, public ILyraTeamAgentInterface
{
	GENERATED_BODY()

public:

	UE_API ULyraLocalPlayer();

	//~UObject接口
	UE_API virtual void PostInitProperties() override;
	//~End of UObject接口

	//~UPlayer接口
	UE_API virtual void SwitchController(class APlayerController* PC) override;
	//~End of UPlayer接口

	//~ULocalPlayer接口
	UE_API virtual bool SpawnPlayActor(const FString& URL, FString& OutError, UWorld* InWorld) override;
	UE_API virtual void InitOnlineSession() override;
	//~End of ULocalPlayer接口

	//~ILyraTeamAgentInterface接口
	UE_API virtual void SetGenericTeamId(const FGenericTeamId& NewTeamID) override;
	UE_API virtual FGenericTeamId GetGenericTeamId() const override;
	UE_API virtual FOnLyraTeamIndexChangedDelegate* GetOnTeamIndexChangedDelegate() override;
	//~End of ILyraTeamAgentInterface接口

	/** 获取此玩家的本地设置，这些设置在进程启动时从配置文件读取，始终有效 */
	UFUNCTION()
	UE_API ULyraSettingsLocal* GetLocalSettings() const;

	/** 获取此玩家的共享设置，这些设置使用保存游戏系统读取，因此在用户登录前可能不正确 */
	UFUNCTION()
	UE_API ULyraSettingsShared* GetSharedSettings() const;

	/** 开始异步加载共享设置的请求，加载或创建新设置后将调用OnSharedSettingsLoaded */
	UE_API void LoadSharedSettingsFromDisk(bool bForceLoad = false);

protected:
	UE_API void OnSharedSettingsLoaded(ULyraSettingsShared* LoadedOrCreatedSettings); // 共享设置加载完成回调

	UE_API void OnAudioOutputDeviceChanged(const FString& InAudioOutputDeviceId); // 音频输出设备改变回调
	
	UFUNCTION()
	UE_API void OnCompletedAudioDeviceSwap(const FSwapAudioOutputResult& SwapResult); // 音频设备交换完成回调

	UE_API void OnPlayerControllerChanged(APlayerController* NewController); // 玩家控制器改变回调

	UFUNCTION()
	UE_API void OnControllerChangedTeam(UObject* TeamAgent, int32 OldTeam, int32 NewTeam); // 控制器队伍改变回调

private:
	UPROPERTY(Transient) // 临时属性，不保存
	mutable TObjectPtr<ULyraSettingsShared> SharedSettings; // 共享设置

	FUniqueNetIdRepl NetIdForSharedSettings; // 用于共享设置的网络ID

	UPROPERTY(Transient) // 临时属性，不保存
	mutable TObjectPtr<const UInputMappingContext> InputMappingContext; // 输入映射上下文

	UPROPERTY()
	FOnLyraTeamIndexChangedDelegate OnTeamChangedDelegate; // 队伍改变委托

	UPROPERTY()
	TWeakObjectPtr<APlayerController> LastBoundPC; // 最后绑定的玩家控制器
};

#undef UE_API